package com.qf.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.qf.feigns.OrderApi;
import com.qf.pojo.R;
import com.qf.service.UserService;
import com.sun.org.apache.bcel.internal.generic.IFEQ;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

//@RestController
//@RequestMapping("/user")
//@RefreshScope //结合配置中心实现热更新使用的。这个注解标注的对象在配置中心发生修够后，会重建
public class UserController2 {

    @Value("${desc}")
    private String desc;

    @Autowired
    private OrderApi orderApi;

    /**
     * 要求方法签名和受保护资源签名一致
     *  可以捕获流控异常或者其他异常
     *
     * 参数列表中最后一个Throwable err 可有可无
     */
    public R findOrders_fb(@PathVariable("id") Integer id,Throwable err) throws InterruptedException{
        err.printStackTrace();
        return R.error().putMsg("fallback....");
    }

    /**
     * 要求方法签名和受保护资源签名一致
     *     只能捕获流控异常
     *
     *  参数列表中最后一个参数必须是BlockException,必须有
     */
    public R findOrders_bh(@PathVariable("id") Integer id, BlockException err) throws InterruptedException{
        err.printStackTrace();
        return R.error().putMsg("blockhandler....");
    }

    /**
     * 返回值和受保护资源一致，参数列表留空
     *  如果有配置fallback或者blockHandler ，这个就不生效
     */
    public R defFallback(Throwable err){

        if (err instanceof BlockException){
            //流控相关
            System.out.println("----------");
        }

        err.printStackTrace();
        return R.error().putMsg("defFallback....");
    }

    @GetMapping("/{id}")
    //标注该资源是受保护资源
    @SentinelResource(value = "findOrders"/*,fallback = "findOrders_fb",blockHandler = "findOrders_bh"*/,defaultFallback = "defFallback")
    public R findOrders(@PathVariable("id") Integer id) throws InterruptedException {
        //演示异常熔断
        if (id == 1){
            throw  new RuntimeException("---");
        }
        //演示慢调用熔断
        if (id == 2){
            Thread.sleep(2000);
        }

        System.out.println("desc: " + desc);
        R r = orderApi.findByUid(id);

        return r;
    }

    /**
     * 用来演示流控模式中的关联模式
     * @return
     */
    @GetMapping("/test1")
    @SentinelResource("test1")
    public R test1(){
        return R.success().putMsg("success...");
    }

    @Autowired
    private UserService userService;
    /**
     * 用来演示流控模式中的链路模式
     * @return
     */
    @GetMapping("/test2")
    @SentinelResource("test2")
    public R test2() throws InterruptedException {
        userService.findById(1);

        return R.success().putMsg("success...");
    }
    /**
     * 用来演示流控模式中的链路模式
     * @return
     */
    @GetMapping("/test3")
    @SentinelResource("test3")
    public R test3() throws InterruptedException {
        userService.findById(1);

        return R.success().putMsg("success...");
    }
}
